package com.nervenets.shopping.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.nervenets.general.jwt.aspect.JwtSecurity;
import com.nervenets.general.service.RedisService;
import com.nervenets.general.service.WebSocketService;
import com.nervenets.general.utils.JodaUtils;
import com.nervenets.general.utils.StringUtils;
import com.nervenets.general.web.BaseController;
import com.nervenets.general.web.params.IdParams;
import com.nervenets.shopping.enumeration.OrderStatus;
import com.nervenets.shopping.hibernate.domain.order.GroupBuyOrderUser;
import com.nervenets.shopping.hibernate.domain.user.UserWxId;
import com.nervenets.shopping.service.GroupBuyOrderUserService;
import com.nervenets.shopping.service.UserService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

@Slf4j
@Controller
@RequestMapping("/api/test")
public class TestController extends BaseController {
    @Reference(version = "1.0.0", check = false)
    private WebSocketService webSocketService;
    @Resource
    private CacheManager cacheManager;
    @Resource
    private WxPayService wxPayService;
    @Resource
    private RedisService redisService;
    @Resource
    private GroupBuyOrderUserService groupBuyOrderUserService;
    @Resource
    private UserService userService;

    @ApiOperation("是否存活")
    @GetMapping("/alive")
    @JwtSecurity(required = false)
    @ResponseBody
    public String alive() {
        return "OK";
    }

    @ApiOperation("测试微信支付到零钱")
    @PostMapping("/entPay")
    @JwtSecurity(required = false)
    public ResponseEntity entPay() {
        EntPayRequest entPayRequest = EntPayRequest.newBuilder()
                .partnerTradeNo(StringUtils.randomString(6).toUpperCase() + JodaUtils.getTimestamp())
                .openid("okf3g4rmYMilxMWFj4g7wqU-zqvo")
                .checkName("NO_CHECK")
                .amount(100)
                .description("测试分红奖励")
                .spbillCreateIp("121.199.15.222")
                .build();
        try {
            return successMessage(wxPayService.getEntPayService().entPay(entPayRequest));
        } catch (WxPayException e) {
            return errorMessage(e.getErrCodeDes());
        }
    }

    @ApiOperation("测试微信退款")
    @PostMapping("/wxRefund")
    @JwtSecurity(required = false)
    public ResponseEntity wxRefund(String outTradeNo, int money) {
        WxPayRefundRequest request = new WxPayRefundRequest();
        request.setOutTradeNo(outTradeNo);
        request.setOutRefundNo(outTradeNo);
        request.setTotalFee(money);
        request.setRefundFee(money);
        request.setRefundDesc("测试退款");
        try {
            return successMessage(wxPayService.refund(request));
        } catch (WxPayException e) {
            return errorMessage(e.getErrCodeDes());
        }
    }

    @ApiOperation("添加白名单")
    @PostMapping("/whiteList")
    @JwtSecurity(required = false)
    public ResponseEntity whiteList(@Valid @RequestBody IdParams params) {
        redisService.set(String.format("bingo-%s", params.getTargetId()), String.valueOf(params.getTargetId()));
        return successMessage();
    }

    @ApiOperation("订单退款")
    @PostMapping("/order/refund")
    @JwtSecurity(required = false)
    public ResponseEntity orderRefund(@Valid @RequestBody IdParams params) {
        GroupBuyOrderUser orderUser = groupBuyOrderUserService.findOne(params.getTargetId(), "订单不存在");
        WxPayRefundRequest request = new WxPayRefundRequest();
        request.setTransactionId(orderUser.getOutTradeNo());
        request.setOutRefundNo(orderUser.getTradeNo());
        request.setTotalFee(orderUser.getMoney());
        request.setRefundFee(orderUser.getMoney());
        request.setRefundDesc("很遗憾，拼团失败，感谢您的参与。");
        WxPayRefundResult refundResult;
        try {
            refundResult = wxPayService.refund(request);
            if ("SUCCESS".equals(refundResult.getReturnCode()) && "SUCCESS".equals(refundResult.getResultCode())) {
                orderUser.setStatus(OrderStatus.refund);
                orderUser.setRefundTime(JodaUtils.getTimestamp());
                orderUser.addLog("拼团失败退款成功");

                if (orderUser.getProduct().getGroupBuyFailedAward() > 0) {
                    orderUser.setReward(Math.max(orderUser.getProduct().getGroupBuyFailedAward(), 0));
                }
                if (orderUser.getReward() > 0) {
                    try {
                        Thread.sleep(500);
                    } catch (Exception ignored) {
                    }
                    rewardHandler(orderUser);
                }
            } else {
                orderUser.addLog("拼团失败退款失败：" + refundResult.getErrCodeDes());
            }
        } catch (WxPayException e) {
            orderUser.addLog("拼团失败退款异常：" + e.getErrCodeDes());
        }
        return successMessage();
    }

    private void rewardHandler(GroupBuyOrderUser orderUser) {
        if (0 == orderUser.getRewardTime()) {
            UserWxId userWxId = userService.findUserWxId(userService.findOne(orderUser.getCreateBy()), wxPayService.getConfig().getAppId());
            if (null != userWxId) {
                EntPayRequest entPayRequest = EntPayRequest.newBuilder()
                        .partnerTradeNo(orderUser.getTradeNo())
                        .openid(userWxId.getOpenId())
                        .checkName("NO_CHECK")
                        .amount(orderUser.getReward())
                        .description("拼团失败，感谢您的参与及推广！")
                        .spbillCreateIp("121.199.15.222")
                        .build();
                EntPayResult entPayResult;
                try {
                    entPayResult = wxPayService.getEntPayService().entPay(entPayRequest);
                    if ("SUCCESS".equals(entPayResult.getReturnCode()) && "SUCCESS".equals(entPayResult.getResultCode())) {
                        orderUser.setRewardTime(JodaUtils.getTimestamp());
                        orderUser.addLog("拼团失败奖励发放成功");
                    } else {
                        orderUser.addLog("拼团失败奖励失败：" + entPayResult.getErrCodeDes());
                    }
                } catch (WxPayException e) {
                    orderUser.addLog("拼团失败奖励异常：" + e.getErrCodeDes());
                }
            }
        }
    }
}
